refactor: storing &mut context in state vars#1926
Conversation
1978f38 to
3754c87
Compare
|
Thanks very much for this @benesjan I just merged a big PR from Leila, which adds lots of docs relating to state variables and storage syntax. Please can you rebase and maybe search for new instances of |
@iAmMichaelConnor Just finished doing all the changes. |
spalladino
left a comment
There was a problem hiding this comment.
Amazing work Jan, thanks for taking this on!
| // docs:start:functions-UncontrainedFunction | ||
| unconstrained fn get_total_points(account: Field) -> u8 { | ||
| let storage = Storage::init(); | ||
| let storage = Storage::init(Option::none(), Option::none()); |
There was a problem hiding this comment.
I was going to suggest adding a method like Storage::init_view() that didn't take any params and set both Option::nones under the hood. But if we're going to hide this behind a macro, no need to polish it up, right?
There was a problem hiding this comment.
Yes, I think it doesn't make sense to implement because of the macro. It would just make Storage a bit more complex and the gain would not be there.
| use dep::aztec::context::{ | ||
| PrivateContext, | ||
| }; | ||
| use dep::aztec::constants_gen::{MAX_NOTES_PER_PAGE, MAX_READ_REQUESTS_PER_CALL}; |
There was a problem hiding this comment.
Did you run a code formatter or something? If so, how? We should get it into the CI so we ensure all our code gets formatted.
There was a problem hiding this comment.
I used rustfmt but it was a semi-manual process because rustfmt fails on unconstrained methods and global vars. How I made it work is that I first renamed unconstrained get_balance to get_balance_unconstrained and removed the global vars and then reverted the changes. The formatting became too ugly so it was worth the hassle but this makes it impossible to use in CI without bigger modifications of rustfmt.
But this actually makes me curious whether to create noirfmt it would be sufficient to create some simple pre and post processors which would make and revert the changes I did manually... 🤔
There was a problem hiding this comment.
FWIW I found a tracking issue in Noir, which doesn't seem prioritised atm: noir-lang/noir#1580
As for using rustfmt, it's an interesting idea, but I'm worried that it'll keep diverging as we add more non-rust features to Noir. Also, removing noir-specific keywords is easy, but adding them back is not, given the file changes introduced by rustfmt. I think we should probably wait.
|
|
||
| // Emit the newly created encrypted note preimages via oracle calls. | ||
| let owner_key = get_public_key(owner); | ||
| let _context = self.context.unwrap(); |
There was a problem hiding this comment.
Nit: avoid using variable names starting with underscore, since they are (or are in most languages, not sure if Rust also) skipped for unused variable checks. As an alternative, you can rename the field to maybeContext, and the unwrapped version to context.
| // Note: Passing the contexts to new(...) just to have an interface compatible with a Map. | ||
| _: Option<&mut PrivateContext>, | ||
| _: Option<&mut PublicContext>, |
There was a problem hiding this comment.
I'm on the fence about this: should we pass both optional contexts to every state var type? Or just the ones they actually need, like in ImmutableSingleton? Still, when we introduce traits, this problem will go away.
| fn init( | ||
| private_context: Option<&mut PrivateContext>, | ||
| public_context: Option<&mut PublicContext>, | ||
| ) -> Self { | ||
| Storage { | ||
| balances: Map::new(1, |s| Set::new(s, ValueNoteMethods)), | ||
| claims: Set::new(2, ClaimNoteMethods), | ||
| balances: Map::new( | ||
| private_context, | ||
| public_context, | ||
| 1, // Storage slot | ||
| |private_context, public_context, slot| { | ||
| Set::new(private_context, public_context, slot, ValueNoteMethods) | ||
| }, | ||
| ), | ||
| claims: Set::new(private_context, public_context, 2, ClaimNoteMethods), |
There was a problem hiding this comment.
I hadn't appreciated how ugly storage declarations would become with this new change. Declaring storage like this doesn't make for a very nice user experience, does it? (I know I initially proposed the change, to clean up calls to methods (by removing the context as a parameter to those calls)... but this is an ugly trade off, and I'm not sure if it's a good one, in hindsight).
I returned to this PR after a breaking change was flagged on discord @benesjan @spalladino - this PR caused a breaking change to storage declarations, and someone was struggling with declaring a double-mapping with this new syntax (and I can understand why :) )
There was a problem hiding this comment.
Declaring a double mapping has become this monstrosity, haha:
Storage {
double_mapping: Map::new(
private_context,
public_context,
1,
|private_context, public_context, slot1| Map::new(
private_context,
public_context,
slot1,
|private_context, public_context, slot2| Set::new(
private_context,
public_context,
slot2,
ValueNoteMethods
)
)
)
}This might have to be classified as "unacceptable syntax"?
Edit: especially when compared to: mapping(uint256 => mapping(uint256 => uint256)) doubleMapping; in Solidity.
There was a problem hiding this comment.
Agree it's horrible, but bear in mind that, as soon as we get traits, we can work with a single context. So the example above would become this. And we can even introduce a DoubleMap struct that abstracts it if we wanted to.
Storage {
double_mapping: Map::new(context, 1,
|context, slot1| Map::new(context, slot1,
|context, slot2| Set::new(context, slot2, ValueNoteMethods)
)
)
}I still think the change is worth it. I'd expect developers to spend more time in contract logic that in storage declaration. And by moving the context into storage initialisation (which we can then hide with a macro), we can keep moving explicit references to context out of the picture, for cleaner contract code.
TLDR: Can you push the Noir team to get traits implemented soon? :-P
There was a problem hiding this comment.
I don't think they'll be implemented for some weeks (at the earliest). Perhaps we could wrap the private_context, public_context "tuple" in a Context type, just to reduce the verbosity of this.
struct Context {
private_context: Option<PrivateContext>,
public_context: Option<PublicContext>,
_is_private: bool
}
And then pass this ugly thing between state variables instead?
A double mapping is a nice idea too!
There was a problem hiding this comment.
Perhaps we could wrap the private_context, public_context "tuple" in a Context type, just to reduce the verbosity of this.
I think that sould be easy to do (annoying, but easy) until we do get traits. Do you want to create an issue and assign it to Otters?
🤖 I have created a new Aztec Packages release --- ## [0.1.0-alpha50](v0.1.0-alpha49...v0.1.0-alpha50) (2023-09-05) ### ⚠ BREAKING CHANGES * update to acvm 0.24.0 ([#1925](#1925)) ### Features * **892:** add hints for matching transient read requests with correspondi… ([#1995](#1995)) ([0955bb7](0955bb7)) * Add support for assert messages & runtime call stacks ([#1997](#1997)) ([ac68837](ac68837)) * **Aztec.nr:** Kernel return types abstraction ([#1924](#1924)) ([3a8e702](3a8e702)) * **ci:** use content hash in build system, restrict docs build to *.ts or *.cpp ([#1953](#1953)) ([0036e07](0036e07)) * do not allow slot 0 in `noir-libs` ([#1884](#1884)) ([54094b4](54094b4)), closes [#1692](#1692) * throwing when submitting a duplicate tx of a settled one ([#1880](#1880)) ([9ad768f](9ad768f)), closes [#1810](#1810) * typos, using Tx.clone functionality, better naming ([#1976](#1976)) ([00bca67](00bca67)) ### Bug Fixes * add retry_10 around ensure_repo ([#1963](#1963)) ([0afde39](0afde39)) * Adds Mac cross compile flags into barretenberg ([#1954](#1954)) ([3aaf91e](3aaf91e)) * bb meta-data ([#1960](#1960)) ([712e0a0](712e0a0)) * **bb.js:** (breaking change) bundles bb.js properly so that it works in the browser and in node ([#1855](#1855)) ([1aa6f59](1aa6f59)) * Benchmark preset uses clang16 ([#1902](#1902)) ([4f7eeea](4f7eeea)) * build ([#1906](#1906)) ([8223be1](8223be1)) * **ci:** Incorrect content hash in some build targets ([#1973](#1973)) ([0a2a515](0a2a515)) * circuits should not link openmp with -DMULTITHREADING ([#1929](#1929)) ([cd1a685](cd1a685)) * compilation on homebrew clang 16.06 ([#1937](#1937)) ([c611582](c611582)) * docs preprocessor line numbers and errors ([#1883](#1883)) ([4e7e290](4e7e290)) * ensure CLI command doesn't fail due to missing client version ([#1895](#1895)) ([88086e4](88086e4)) * error handling in acir simulator ([#1907](#1907)) ([165008e](165008e)) * Fix off by one in circuits.js when fetching points from transcript ([#1993](#1993)) ([cec901f](cec901f)) * format.sh issues ([#1946](#1946)) ([f24814b](f24814b)) * master ([#1981](#1981)) ([6bfb053](6bfb053)) * More accurate c++ build pattern ([#1962](#1962)) ([21c2f8e](21c2f8e)) * polyfill by bundling fileURLToPath ([#1949](#1949)) ([1b2de01](1b2de01)) * Set correct version of RPC & Sandbox when deploying tagged commit ([#1914](#1914)) ([898c50d](898c50d)) * typescript lookup of aztec.js types ([#1948](#1948)) ([22901ae](22901ae)) * unify base64 interface between mac and linux (cherry-picked) ([#1968](#1968)) ([ee24b52](ee24b52)) * Update docs search config ([#1920](#1920)) ([c8764e6](c8764e6)) * update docs search keys ([#1931](#1931)) ([03b200c](03b200c)) ### Miscellaneous * **1407:** remove forwarding witnesses ([#1930](#1930)) ([cc8bc8f](cc8bc8f)), closes [#1407](#1407) * **1879:** add use of PrivateKernelPublicInputs in TS whenever relevant ([#1911](#1911)) ([8d5f548](8d5f548)) * acir tests are no longer base64 encoded ([#1854](#1854)) ([7fffd16](7fffd16)) * Add back double verify proof to test suite ([#1986](#1986)) ([f8688d7](f8688d7)) * add CLI test to canary flow ([#1918](#1918)) ([cc68958](cc68958)), closes [#1903](#1903) * Add safemath noir testing ([#1967](#1967)) ([cb1f1ec](cb1f1ec)) * **Aztec.nr:** remove implicit imports ([#1901](#1901)) ([c7d5190](c7d5190)) * **Aztec.nr:** Remove the open keyword from public functions ([#1917](#1917)) ([4db8603](4db8603)) * **ci:** build docs on every pr ([#1955](#1955)) ([c200bc5](c200bc5)) * Enable project-specific releases for dockerhub too ([#1721](#1721)) ([5d2c082](5d2c082)) * reduce max circuit size in bb binary ([#1942](#1942)) ([c61439b](c61439b)) * Reference noir master for acir tests ([#1969](#1969)) ([86b72e1](86b72e1)) * remove debug output from `run_acir_tests` script ([#1970](#1970)) ([74c83c5](74c83c5)) * storing `&mut context` in state vars ([#1926](#1926)) ([89a7a3f](89a7a3f)), closes [#1805](#1805) * sync bb master ([#1947](#1947)) ([eed58e1](eed58e1)) * update to acvm 0.24.0 ([#1925](#1925)) ([e728304](e728304)) * Update to acvm 0.24.1 ([#1978](#1978)) ([31c0a02](31c0a02)) * updating docs to clang16 ([#1875](#1875)) ([a248dae](a248dae)) ### Documentation * **keys:** Complete addresses are now broadcast ([#1975](#1975)) ([92068ad](92068ad)), closes [#1936](#1936) * limitations, privacy, roadmap ([#1759](#1759)) ([0cdb27a](0cdb27a)) * put dev docs before spec ([#1944](#1944)) ([f1b29cd](f1b29cd)) * storage and state variables ([#1725](#1725)) ([fc72f84](fc72f84)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

Fixes #1805
Checklist:
Remove the checklist to signal you've completed it. Enable auto-merge if the PR is ready to merge.